<?php

namespace common\components\db;

use Yii;
use yii\db\Command as BaseCommand;
use yii\db\Expression;

class Command extends BaseCommand
{
  
    /**
     * 对mysql gone aways的问题进行处理，如果出现这个问题那么重新链接数据库
     * Executes the SQL statement.
     * This method should only be used for executing non-query SQL statement, such as `INSERT`, `DELETE`, `UPDATE` SQLs.
     * No result set will be returned.
     * @return int number of rows affected by the execution.
     * @throws Exception execution failed
     */
    public function execute()
    {
       try {
            return parent::execute();
        } catch (\Exception $e) {
            $this->db->handleException($e);
            return parent::execute();
        }
    }
  
    /**
     * * 对mysql gone aways的问题进行处理，如果出现这个问题那么重新链接数据库
     * Performs the actual DB query of a SQL statement.
     * @param string $method method of PDOStatement to be called
     * @param int $fetchMode the result fetch mode. Please refer to [PHP manual](http://www.php.net/manual/en/function.PDOStatement-setFetchMode.php)
     * for valid fetch modes. If this parameter is null, the value set in [[fetchMode]] will be used.
     * @return mixed the method execution result
     * @throws Exception if the query causes any problem
     * @since 2.0.1 this method is protected (was private before).
     */
    protected function queryInternal($method, $fetchMode = null)
    {  
        try {
            return parent::queryInternal($method, $fetchMode);
        } catch (\Exception $e) {
            $this->db->handleException($e);
            return parent::queryInternal($method, $fetchMode);
        } catch (\yii\db\Exception $e) {
            $this->db->handleException($e);
            return parent::queryInternal($method, $fetchMode);            
        }
        
    }

    /**
     * 批量插入更新数据库
     * @param string $table
     * @param array $columns
     * @param array $rows: 需要插入或则更新的数据
     * @param string $updateNames: 需要更新字段
     * @param string $params: 其他参数
     * @return object
     */
    public function batchUpsert($table, $columns, $rows, $updateNames = [], $params = [])
    {
        $table = $this->db->quoteSql($table);
        $columns = array_map(function ($column) {
            return $this->db->quoteSql($column);
        }, $columns);

        $params = [];
        $sql = $this->db->getQueryBuilder()->batchInsert($table, $columns, $rows, $params);
        $updateColumns = [];
        if (empty($updateNames)) {
            $updateNames = $columns;
        }
        foreach ($updateNames as $name) {
            $value = new Expression('VALUES(' . $this->db->quoteColumnName($name) . ')');
            $placeholder = $this->db->getQueryBuilder()->buildExpression($value, $params);
            $sets[] = $this->db->quoteColumnName($name) . '=' . $placeholder;
        }

        $sql .= ' ON DUPLICATE KEY UPDATE ' . implode(', ', $sets);
        $this->setRawSql($sql);
        $this->bindValues($params);

        return $this;
    }
}